package xyz.wadewhy.basicstest.designPatterns.AgencyModel;

import java.lang.reflect.Proxy;

/**
 * 用中介卖房子介绍代理模式
 */
interface SellHouse {
    /**
     * 售卖接口
     */
    void sell();
}

/**
 * 房东售卖
 */
class Landlord implements SellHouse {

    @Override
    public void sell() {
        System.out.println("房东售卖业务....");
    }
}

/**
 * 静态代理
 * 中介代理售卖
 * 1.代理类可以在不修改被代理对象中的业务逻辑的情况下，增加自己的业务功能
 * 2.代理类和被代理类应该共同实现一个接口，或者共同继承某个类
 * 3.代理类中组合聚合被代理类
 */
class ProxyPoint implements SellHouse {
    /**
     * 组合，聚合 房东类
     */
    private final Landlord landlord = new Landlord();

    @Override
    public void sell() {
        //中介自己的业务，抽取佣金
        System.err.println("中介抽取佣金....");
        //真正地售卖业务，签租赁合同等
        landlord.sell();
    }
}

/**
 * 动态代理
 */
class DynamicProxy {
    private final Landlord landlord = new Landlord();

    public SellHouse getProxy() {
        return (SellHouse) Proxy.newProxyInstance(
                landlord.getClass().getClassLoader(),
                landlord.getClass().getInterfaces(),
                /**
                 *  proxy ： 代理对象
                 *  method ： 对应于在代理对象上调用的接口方法的 Method 实例
                 *  args ： 代理对象调用接口方法时传递的实际参数
                 */
                (proxy, method, args) -> {
                    System.err.println("动态代理 房产中介收取手续费");
                    // 执行真实对象  如果有返回值就将它返回回去
                    return method.invoke(landlord, args);
                }
        );
    }
}


class TestDemoV1 {
    public static void main(String[] args) {
        ProxyPoint point = new ProxyPoint();
        point.sell();
        DynamicProxy dynamicProxy = new DynamicProxy();
        dynamicProxy.getProxy().sell();
    }
}